#include "./tlsf.h"
#include "../mem_inner.h"
#include "loger.h"

/* 内存管理-tlsf */


#if defined (CONFIG_MEM_TYPE_TLSF)

/* #define */
#define TAG "TLSF-PORT"

/* static var */

static size_t tlsf_mem_used = 0;
static size_t tlsf_mem_total = 0;


/* static sal func */

static void *_init(void *obj, void *addr_start, void *addr_end)
{
    size_t size;
    tlsf_t tlsf_obj;

    if (obj) return NULL;

    if (addr_start >= addr_end)
    {
        return NULL;
    }
    else
    {
        size = (uint32_t)addr_end - (uint32_t)addr_start;
    }

    if (obj == NULL)
    {
        tlsf_obj = tlsf_create_with_pool(addr_start, size);
        if (tlsf_obj == NULL) return NULL;
    }

    // LOG_I(TAG, "mem_tlsf_sal init = 0x%08X (0x%08X - 0x%08X)", (uint32_t)tlsf_obj, (uint32_t)addr_start, (uint32_t)addr_end);

    return tlsf_obj;
}

static void _free(void *obj, void *ptr)
{
    if (obj)
    {
        tlsf_free(obj, ptr);
    }
}

static void *_malloc(void *obj, size_t bytes)
{
    void *ptr = NULL;

    if (obj)
    {
        ptr = tlsf_malloc(obj, bytes);
    }
    return ptr;
}

static void *_realloc(void *obj, void *ptr, size_t bytes)
{
    if (obj)
    {
        ptr = tlsf_realloc(obj, ptr, bytes);
    }
    return ptr;
}

static void tlsf_work_cb(void *ptr, size_t size, int used, void *user)
{
    if (used)
    {
        tlsf_mem_used += size;
    }
    tlsf_mem_total += size;
}

static void _get_info(void *obj, uint32_t *total, uint32_t *used, uint32_t *max_used)
{
    tlsf_mem_used = 0;
    tlsf_mem_total = 0;

    tlsf_walk_pool(tlsf_get_pool(obj), tlsf_work_cb, 0);

    *total = tlsf_mem_total;
    *used = tlsf_mem_used;
    *max_used = tlsf_mem_used;
}


/* export */


const _mem_sal_opt mem_tlsf_sal_opt = 
{
    .name = "TLSF",
    .func_init = _init,
    .func_free = _free,
    .func_malloc = _malloc,
    .func_realloc = _realloc,
    .func_get_info = _get_info,
};


#endif // CONFIG_MEM_TYPE_TLSF
